package com.lyn.image_tools;

import android.graphics.Bitmap;
import android.view.Surface;

/**
 * 图像处理工具类
 *
 * @author:longyongning
 * @date:2021/11/19
 * @description:
 */
public class ImageUtil {

    private byte[] BITMAP_TO_NV21_DATA;

    public byte[] bitmapToNV21(Bitmap bitmap) {
        if (bitmap == null) {
            return null;
        }
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        boolean isExist = false;
        if (BITMAP_TO_NV21_DATA != null) {
            if (BITMAP_TO_NV21_DATA.length == width * height * 3 / 2) {
                isExist = true;
            }
        }
        if (!isExist) {
            BITMAP_TO_NV21_DATA = new byte[width * height * 3 / 2];
        }
        nativeBitmapToNV21(bitmap, BITMAP_TO_NV21_DATA);
        return BITMAP_TO_NV21_DATA;
    }


    private byte[] CENTER_CUT_NV21_DATA;

    /**
     * 居中裁切NV21
     *
     * @param srcNV21
     * @param srcWidth
     * @param srcHeight
     * @param outWidth
     * @param outHeight
     * @return
     */
    public byte[] centerCutNV21(byte[] srcNV21, int srcWidth, int srcHeight, int outWidth, int outHeight) {
        if (srcWidth < outWidth || srcHeight < outHeight) {
            return srcNV21;
        }
        if (CENTER_CUT_NV21_DATA == null) {
            CENTER_CUT_NV21_DATA = new byte[outWidth * outHeight * 3 / 2];
        } else {
            if (CENTER_CUT_NV21_DATA.length != outWidth * outHeight) {
                CENTER_CUT_NV21_DATA = new byte[outWidth * outHeight * 3 / 2];
            }
        }
        int outLeft = (srcWidth - outWidth) / 2;
        int outTop = (srcHeight - outHeight) / 2;
        nativeClipNv21ToNv21(srcNV21, srcWidth, srcHeight, CENTER_CUT_NV21_DATA, outLeft, outTop, outWidth, outHeight);
        return CENTER_CUT_NV21_DATA;
    }

    /**
     * 镜像NV21
     *
     * @param srcNV21
     * @param srcWidth
     * @param srcHeight
     * @return
     */
    public void mirrorNV21(byte[] srcNV21, int srcWidth, int srcHeight) {
        nativeMirrorNV21(srcNV21, srcWidth, srcHeight);
    }

    public enum Rotate {
        ROTATE_90, ROTATE_180, ROTATE_270;
    }

    private byte[] ROTATE_NV21_DATA;

    /**
     * 旋转NV21
     *
     * @param srcNV21
     * @param srcWidth
     * @param srcHeight
     * @return
     */
    public byte[] rotateNV21(byte[] srcNV21, int srcWidth, int srcHeight, Rotate rotate) {
        if (srcNV21 == null ||rotate==null) return null;
        if (ROTATE_NV21_DATA==null){
            ROTATE_NV21_DATA=new byte[srcWidth*srcHeight*3/2];
        }else {
            if (ROTATE_NV21_DATA.length!=srcWidth*srcHeight*3/2){
                ROTATE_NV21_DATA=new byte[srcWidth*srcHeight*3/2];
            }
        }
        switch (rotate) {
            case ROTATE_90:
                nativeRotateNV21(srcNV21, srcWidth, srcHeight, ROTATE_NV21_DATA, 90);
                break;
            case ROTATE_180:
                nativeRotateNV21(srcNV21, srcWidth, srcHeight, ROTATE_NV21_DATA, 180);
                break;
            case ROTATE_270:
                nativeRotateNV21(srcNV21, srcWidth, srcHeight, ROTATE_NV21_DATA, 270);
                break;
        }
        return ROTATE_NV21_DATA;
    }

    private int[] NV21_TO_BGR_DATA;

    /**
     * NV21转RGB
     *
     * @param srcNV21
     * @param srcWidth
     * @param srcHeight
     * @return
     */
    public int[] nv21ToRgb(byte[] srcNV21, int srcWidth, int srcHeight, boolean isRgb) {
        if (NV21_TO_BGR_DATA == null) {
            NV21_TO_BGR_DATA = new int[srcWidth * srcHeight];
        } else {
            if (NV21_TO_BGR_DATA.length != srcWidth * srcHeight) {
                NV21_TO_BGR_DATA = new int[srcWidth * srcHeight];
            }
        }
        nativeNV21ToRGB(srcNV21, srcWidth, srcHeight, NV21_TO_BGR_DATA, isRgb);
        return NV21_TO_BGR_DATA;
    }

    /**
     * 设置surface
     * @param surface
     */
    public void setSurface(Surface surface){
        nativeSetSurface(surface);
    }

    /**
     * surface 渲染 显示bgr
     * @param bgr
     * @param width
     * @param height
     */
    public void showRgbToSurface(int[] bgr, int width, int height) {
        nativeShowBGRToSurface(bgr, width, height);
    }

    public native void nativeBitmapToNV21(Bitmap bitmap, byte[] outNv21);

    public native void nativeClipNv21ToNv21(byte[] srcNV21, int srcWidth, int srcHeight, byte[] outNV21, int outLeft, int outTop, int outWith, int outHeight);

    public native void nativeMirrorNV21(byte[] srcNV21, int srcWidth, int srcHeight);

    public native void nativeRotateNV21(byte[] srcNV21, int srcWidth, int srcHeight, byte[] outNV21, int angle);

    public native void nativeNV21ToRGB(byte[] srcNV21, int srcWidth, int srcHeight, int[] rgb, boolean isRgb);

    public native void nativeSetSurface(Surface surface);

    public native void nativeShowBGRToSurface(int[] bgr, int width, int height);


    static {
        System.loadLibrary("ImageUtil");
    }
}
